package com.zzl.springboot_mybatis_demo.aspect;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * Description：@MyAnnotation注解切面
 * Created by 朱正磊 on 2019-08-25 20:05
 */
@Aspect
@Component
public class MyAnnotationAspect {

    /**
     * description：处理业务逻辑
     * user 朱正磊
     * time 2019-08-25 20:47
     * @param point 切点
     * @param myAnnotation 自定义注解
     * @return 返回切点执行结果
     * @throws Throwable 异常
     */
    @Around("@annotation(myAnnotation)")
    public Object doAround(ProceedingJoinPoint point, MyAnnotation myAnnotation) throws Throwable {
        System.out.println(getValue(myAnnotation.value(), point));
        System.out.println(myAnnotation.key());
        System.out.println("-------开始拦截");
        System.out.println("类路径名：" + point.getSourceLocation().getWithinType().getName());
        System.out.println("方法名：" + point.getSignature().getName());
        Object proceed = point.proceed();
        System.out.println("-------结束拦截");
        return proceed;
    }

    /**
     * description：获取EL表达式参数替换后的字符串值
     * user 朱正磊
     * time 2019-08-25 22:27
     * @param key el表达式字符串，占位符以#开头
     * @param point 切点
     * @return 返回EL表达式参数替换后的字符串值
     */
    private String getValue(String key, ProceedingJoinPoint point) {
        //不符合EL表达式占位符格式，原值返回
        if (!(StringUtils.isNotBlank(key) && '#' == key.toCharArray()[0])) {
            return key;
        }

        //获取目标方法并根据方法获取形参列表
        Method method = ((MethodSignature) point.getSignature()).getMethod();
        String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(method);

        //获取实参列表
        Object[] args = point.getArgs();

        //返回EL表达式参数替换后的字符串值
        return SpelParser.getValue(key, parameterNames, args);
    }

}
